package{

import flash.utils.Dictionary;
import flash.xml.*;

import org.openzoom.flash.descriptors.*;
import org.openzoom.flash.utils.math.clamp;

public final class EslideDescriptor extends ImagePyramidDescriptorBase
                           implements IImagePyramidDescriptor
{
    //--------------------------------------------------------------------------
    //
    //  Namespaces
    //
    //--------------------------------------------------------------------------
   
    private var rdf:Namespace = new Namespace ("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
	private var dc:Namespace = new Namespace ("http://purl.org/dc/elements/1.1/");
	private var dp:Namespace = new Namespace ("http://www.telemed.uniud.it/dp/0.1/");
	private var dcq:Namespace = new Namespace ("http://purl.org/dc/qualifiers/1.0/");

	//variables
	
	private var extension : String;
    private var data : XML;
    private var levels : Dictionary = new Dictionary();
   
	//11/09/09
	private var tileW : int;
	private var tileH : int;
	
	private var imgType : String;
	
	private var numLvl : int;
	
	private var imageWidth : int;
	private var imageHeight : int;
	
	public var maxZoom : Number; //17/09/09
	
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Constructor.
     */
     
    public function EslideDescriptor( source : String, data:XML)
    {
        this.data = data;
		this.source = source;
        parseXML( data );
        levels = computeLevels(numLvl);
    }
    
    
    
    public function parseXML(data:XML)
    {		
		//relation micron/pixel
		var micronX = data.rdf::Description.dp::resolution.dp::x;
		var micronY = data.rdf::Description.dp::resolution.dp::y;
		
		//tile size micron
		var imsizeX = data.rdf::Description.dp::imsize.dp::x;
		var imsizeY = data.rdf::Description.dp::imsize.dp::y;
		
		//gives tile size in pixel
		tileW = imsizeX;
        this._tileWidth = tileW; //14/09/09
        tileH = imsizeY;
        this._tileHeight = tileH; //14/09/09
        
        imgType = "jpg";
        this._type = imgType;
        
        var numDescr:int = data.children().length();
        
        numLvl = numDescr-2;
        this._numLevels = numLvl;
        
        var rangeX = data.rdf::Description[1].dp::matrix.dp::xrange;
		var	nTileX:Array = rangeX.split("-");
		var columns = nTileX[1];
		var imgW:int = columns*tileW;
		
		var rangeY = data.rdf::Description[1].dp::matrix.dp::yrange;
		var	nTileY:Array = rangeY.split("-");
		var rows = nTileY[1];
		var imgH:int = rows*tileH;
		 
        imageWidth = imgW;
        this._width = imageWidth; //14/09/09
        imageHeight = imgH;
        this._height = imgH; //14/09/09
        
        //17/09/09
        // maximum Zoom allowed for the considered set (minimum zoom = 1, set in .mxml file)
        maxZoom = data.rdf::Description[1].dp::magnification;
       
        
    }
    
    public function getTileURL( level : int, column : int, row : int ) : String
    {
        var path : String  = this.source.substring( 0, source.length - 12 ) //12 = caseInfo.RDF
        //e.g. 'C:/prototipo_local/m021/5x/m0215x6-16.jpg';
    	//e.g. 'C:/prototipo_local/m021/10x/m02110x43-52.jpg
    	extension = "jpg";
        var actualLevel = data.rdf::Description[numLvl-level];
        var pathLevelBuf =  actualLevel.attributes();
    	
    	var pathLevel = pathLevelBuf.substring(2);
    	var completePath =  [ path, pathLevel, row+1, "-", column+1, ".", extension ].join("")
    	return completePath;
        
    }
	
	public function computeLevels(nLev:int):Dictionary
	{
		var levels:Dictionary = new Dictionary()
		for (var ind:int = 0; ind<nLev; ind++)
		{
	        var rangeX = data.rdf::Description[ind+1].dp::matrix.dp::xrange;
			var	nTileX:Array = rangeX.split("-");
			var columns = nTileX[1];
			var imgWidth:int = columns*tileW;
			
			var rangeY = data.rdf::Description[ind+1].dp::matrix.dp::yrange;
			var	nTileY:Array = rangeY.split("-");
			var rows = nTileY[1];
			var imgHeight:int = rows*tileH;
			 
	        var newIndex:int = nLev-1-ind; 
	        
	        var level:ImagePyramidLevel = new ImagePyramidLevel(this,newIndex,imgWidth,imgHeight,columns,rows)
	        levels[newIndex] = level;
	        
        }
        return levels;   
	}
	
    /**
     * @inheritDoc
     */
     //11/09/09
    public override function getLevelAt( index : int ) : IImagePyramidLevel
    {
        return IImagePyramidLevel( levels[ index ] )
    }

    /**
     * @inheritDoc
     */
    public function getLevelForSize( width : Number,
                                        height : Number ) : IImagePyramidLevel
    {
    	var level : IImagePyramidLevel;
    	
    	for(var i : int = numLvl-1; i >=0; i--)
    	{
    		level = getLevelAt(i);
    		if(level.width < width || level.height < height ){ 
    			break;
    		}
    		
    	}
    
    	return getLevelAt( clamp(level.index+1,0,numLvl-1)).clone(); 
    	
    }

    /**
     * @inheritDoc
     */
    public function clone() : IImagePyramidDescriptor
    {
    	return new EslideDescriptor(source, new XML( data ) );
    }
}
}
 
